package oss.git;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import oss.util.FileMD5Utils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class GitAsOssUtil {
    protected static String origin;
    protected static String user;
    protected static String password;
    protected static String path;

    protected static String raw;

    private static Git currentGit;

    static {

        Properties properties = new Properties();
        try {
            properties.load(ClassLoader.getSystemResourceAsStream("git.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        origin = properties.getProperty("git.origin");
        user = properties.getProperty("git.user");
        password = properties.getProperty("git.password");
        path = properties.getProperty("git.path");
        raw = properties.getProperty("git.origin.raw");

        try {
            currentGit = checkoutGit();
        } catch (Exception e1) {
            try {
                currentGit = openGit();
            } catch (Exception e2) {

            }
        }
    }

    private static Git openGit() throws IOException {
        Git git = Git.open(new File(path));
        return git;
    }

    private static boolean checkNoCommit(String md5) {
        try {
            Iterable<RevCommit> call = currentGit.log().call();
            for (RevCommit revCommit : call) {
                if (revCommit.getFullMessage().equals(md5)) {
                    return false;
                }
            }
        } catch (GitAPIException e) {
            e.printStackTrace();
        }

        return true;
    }


    public static String add(String fileName, InputStream is) {
        try {
            String fileMD5 = FileMD5Utils.getFileMD5(is);
            String md5fileName = fileMD5 + FilenameUtils.EXTENSION_SEPARATOR + FilenameUtils.getExtension(fileName);
            if (checkNoCommit(fileMD5)) {
                String newFileName = path + File.separator + md5fileName;
                IOUtils.copy(is, FileUtils.openOutputStream(new File(newFileName)));
                DirCache index = currentGit.add().addFilepattern(md5fileName).call();
                RevCommit commit = currentGit.commit().setMessage(fileMD5).call();
                currentGit.push().setCredentialsProvider(new UsernamePasswordCredentialsProvider(user, password)).call();
            }
            return raw + md5fileName;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param file
     * @return
     * @throws IOException
     * @throws GitAPIException
     */
    public static String add(File file) {
        try {
            return add(file.getName(), FileUtils.openInputStream(file));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static Git checkoutGit() throws GitAPIException {
        File client = new File(path);
        client.mkdir();
        try (Git result = Git.cloneRepository().setURI(origin)
                .setDirectory(client)
                .call()) {
            return result;
        }
    }


    public static void main(String[] args) throws Exception {
        System.out.println(GitAsOssUtil.add(new File("D://1.png")));
    }


}
